package org.springblade.modules.api.controller;


import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springblade.common.constant.RedisKeyConstant;
import org.springblade.common.exception.TrainingServiceException;
import org.springblade.common.utils.CommonUtil;
import org.springblade.core.jwt.JwtUtil;
import org.springblade.core.launch.constant.TokenConstant;
import org.springblade.core.redis.cache.BladeRedis;
import org.springblade.core.secure.BladeUser;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.constant.BladeConstant;
import org.springblade.core.tool.support.Kv;
import org.springblade.core.tool.utils.Func;
import org.springblade.core.tool.utils.StringUtil;
import org.springblade.core.tool.utils.WebUtil;
import org.springblade.modules.api.service.ApiService;
import org.springblade.modules.api.vo.ApiUserInfo;
import org.springblade.modules.auth.enums.UserLoginEnum;
import org.springblade.modules.auth.provider.ITokenGranter;
import org.springblade.modules.auth.provider.TokenGranterBuilder;
import org.springblade.modules.auth.provider.TokenParameter;
import org.springblade.modules.auth.utils.TokenUtil;
import org.springblade.modules.system.entity.UserInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;

@RestController
@RequestMapping("blade-api/sso")
@Api(value = "sso登录相关", tags = "sso登录相关接口")
@Slf4j
public class SsoController {

	@Autowired
	private ApiService apiService;
	@Autowired
	private CommonUtil commonUtil;
	@Autowired
	private BladeRedis bladeRedis;

	@Value("${jxc.sso.manageLoginUrl}")
	private String manageLoginUrl;
	@Value("${jxc.sso.clientLoginUrl}")
	private String clientLoginUrl;

	@Value("${jxc.sso.loginEnv}")
	private boolean loginEnv;

	@Value("${manageUrl}")
	private String manageUrl;

	@Value("${clientUrl}")
	private String clientUrl;

	/**
	 * 1.前端判断路径有无ticket 没有就去sso登录
	 * 2.sso登陆完之后  sso那边会带着ticket重定向到我们系统的首页 例如这样 http://172.22.60.24:1888/wel/index?ticket=0000000
	 * 3.有ticket的话，拿ticket换token
	 */
	@GetMapping("/login")
	@ApiOperationSupport(order = 1)
	@ApiOperation(value = "管理后台前往sso登录", notes = "管理后台前往sso登录")
	public R ssoLogin() {

		/**
		 * 前面的 sso登录地址
		 * redirect_url sso登录成功后要跳转的地址
		 */
		return R.data(manageLoginUrl);
	}

	@GetMapping("/client-login")
	@ApiOperationSupport(order = 1)
	@ApiOperation(value = "客户端前往sso登录", notes = "客户端前往sso登录")
	public R ssoClientLogin() {
		/**
		 * 前面的 sso登录地址
		 * redirect_url sso登录成功后要跳转的地址
		 */
		return R.data(clientLoginUrl);
	}

	/**
	 * SSO登录
	 * @param ticket
	 */
	@GetMapping("/ticket-token")
	@ApiOperationSupport(order = 3)
	@ApiOperation(value = "根据ticket获取token", notes = "根据ticket获取token")
	public Kv ticketExchangeToken(String ticket) {
		String username = "";
		String account="";
		//1.根据ticket获取用户信息
		if (true) {
			ApiUserInfo ssoUserInfo = apiService.getUserInfo(ticket);
			if (null == ssoUserInfo) throw new TrainingServiceException("没有获取到用户信息");
			if (null == ssoUserInfo.getCardNo()) throw new TrainingServiceException("该用户没有身份证");
//			username=ssoUserInfo.getCardNo();
			username=ssoUserInfo.getUserName();
			account=ssoUserInfo.getCardNo();
		}
		//2.根据用户信息获取token
		String password = "21232f297a57a5a743894a0e4a801fc3";
		String tenantId = BladeConstant.ADMIN_TENANT_ID;
		String deptId = "";
		String roleId = "";

		Kv authInfo = Kv.create();

		String grantType = WebUtil.getRequest().getParameter("grant_type");
		String refreshToken = WebUtil.getRequest().getParameter("refresh_token");

		String userType = Func.toStr(WebUtil.getRequest().getHeader(TokenUtil.USER_TYPE_HEADER_KEY), TokenUtil.DEFAULT_USER_TYPE);
		TokenParameter tokenParameter = new TokenParameter();
		tokenParameter.getArgs().set("tenantId", tenantId)
			.set("username", username)
			.set("password", password)
			.set("grantType", grantType)
			.set("refreshToken", refreshToken)
			.set("userType", userType)
			.set("deptId", deptId)
			.set("roleId", roleId)
			.set("account", account)
			.set("userLoginType", UserLoginEnum.SSO.getCategory());


		ITokenGranter granter = TokenGranterBuilder.getGranter(grantType);
		UserInfo userInfo = granter.grant(tokenParameter);
		if (userInfo == null || userInfo.getUser() == null) {
			return authInfo.set("error_code", HttpServletResponse.SC_BAD_REQUEST).set("error_description", "用户名或密码不正确");
		}

		if (Func.isEmpty(userInfo.getRoles())) {
			return authInfo.set("error_code", HttpServletResponse.SC_BAD_REQUEST).set("error_description", "未获得用户的角色信息");
		}

		commonUtil.initUserBaseCache(userInfo.getUser().getId());//初始化用户扩展表缓存
		return TokenUtil.createAuthInfo(userInfo);
	}


	@GetMapping("/oauth/logout")
	@ApiOperationSupport(order = 10)
	@ApiOperation(value = "管理后台退出登录")
	public R logout() {
		//本系统退出登录
		BladeUser user = AuthUtil.getUser();
//		if (user != null && jwtProperties.getState()) {
		if (user != null) {
			//sso退出登录
			try {
				String token = JwtUtil.getToken(WebUtil.getRequest().getHeader(TokenConstant.HEADER));
				JwtUtil.removeAccessToken(user.getTenantId(), String.valueOf(user.getUserId()), token);
				boolean ssoLogout = apiService.ssoLogout(user.getUserId());
			} catch (Exception e) {
				log.info(e.getMessage());
			}
		}
//		String url = "http://172.22.60.24:1888";
//		String url="http://peixun.4307.com:1888";
//		String url="training.bjhgxt.com"; //云端
		Kv.create().set("success", "true").set("msg", "success");
		return R.data(manageUrl);
	}

	@GetMapping("/oauth/logout-client")
	@ApiOperationSupport(order = 11)
	@ApiOperation(value = "客户端退出登录")
	public R logoutClient() {
		//本系统退出登录
		BladeUser user = AuthUtil.getUser();
		if (user != null) {
			//sso退出登录
			try {
				String token = JwtUtil.getToken(WebUtil.getRequest().getHeader(TokenConstant.HEADER));
				JwtUtil.removeAccessToken(user.getTenantId(), String.valueOf(user.getUserId()), token);
				boolean ssoLogout = apiService.ssoLogout(user.getUserId());
			} catch (Exception e) {
				log.info(e.getMessage());
			}
		}

		String url = "http://172.22.60.24:3000";
//		String url="http://peixun.4307.com:3000";
//		String url="training-client.bjhgxt.com";//云端
		Kv.create().set("success", "true").set("msg", "success");
		return R.data(clientUrl);
	}

	@GetMapping("/user-status")
	@ApiOperationSupport(order = 12)
	@ApiOperation(value = "用户登陆状态检测")
	public R userLoginStatus(Integer type) {
//		TODO 待放开
		BladeUser user = AuthUtil.getUser();
		if (null == user) {
			if (1 == type) {//管理后台
//				return R.data("http://peixun.4307.com:1888","登录失效");
//				return R.data("training.bjhgxt.com","登录失效");//云端
//				return R.data("http://172.22.60.24:1888", "登录失效");
				return R.data(manageUrl, "登录失效");

			}
			if (2 == type) {//客户端
//				return R.data("http://peixun.4307.com:3000","登录失效");
				return R.data(clientUrl,"登录失效");
//				return R.data("training-client.bjhgxt.com","登录失效");//云端
//				return R.data("http://172.22.60.24:3000", "登录失效");
			}
		}
//		if (user != null) {
//			UserBaseEntity userBaseEntity = userBaseService.getOne(Wrappers.<UserBaseEntity>query().lambda().eq(UserBaseEntity::getUserId, user.getUserId()));
//			String ssoToken=bladeRedis.get(RedisKeyConstant.JXC_SSO_TOKEN+userBaseEntity.getIdCard());
//			if (StringUtil.isBlank(ssoToken) || !apiService.getSsoTokenStatus(userBaseEntity.getIdCard()) ){
//				if (1==type){
//					return R.data(manageLoginUrl,"登录失效");
//				}
//				if (2==type){
//					return R.data(clientLoginUrl,"登录失效");
//				}
//			}
//		}

		return R.data("");
	}


	@GetMapping("/ctrl/test")
	@ApiOperationSupport(order = 19)
	@ApiOperation(value = "模拟根据ticket获取用户信息")
	public R ticketDemo(String ticket) {
		return R.data(apiService.getUserInfo(ticket));
	}


	@GetMapping("/ctrl/sso-status")
	@ApiOperationSupport(order = 20)
	@ApiOperation(value = "模拟根据idcard获取用户登录状态")
	public R ticketStatus(String idcard) {
		return R.data(apiService.getSsoTokenStatus(idcard));
	}

	@GetMapping("/ctrl/sso-status-idcard")
	@ApiOperationSupport(order = 21)
	@ApiOperation(value = "模拟根据idcard获取用户登录状态")
	public R idcardStatus(String idcard) {
		String result = "正常";
		String ssoToken = bladeRedis.get(RedisKeyConstant.JXC_SSO_TOKEN + idcard);
		if (StringUtil.isBlank(ssoToken) || !apiService.getSsoTokenStatus(idcard)) {
			result = "不正常";
		}
		return R.data(result);
	}

}
